package com.tjbklx1.threadpool.test;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import com.tjbklx1.threadpool.CommonThreadPool;
import com.tjbklx1.threadpool.IAsynchronousHandler;
import com.tjbklx1.threadpool.ThreadPoolAdaptor;
import com.tjbklx1.threadpool.ThreadPoolParameterVO;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

public abstract class MyThreadPool {
    //临时日志
    private static final Logger LOGGER = LoggerFactory.getLogger(MyThreadPool.class);

    //private static ExecutorService execute = init();

    private static final long  EXECUTETIME = 10000L;

    // --------- 新线程池start ---------
    private static ThreadPoolTaskExecutor executorNew = null;

    static {
        Properties ps = getThreadPoolConfig();
        try{
            LOGGER.debug("【临时日志1】 开始初始化ThreadPoolTaskExecutor");
            executorNew = new ThreadPoolTaskExecutor();
            executorNew.setCorePoolSize(Integer.parseInt(ps.getProperty("corePoolSize", "5")));
            executorNew.setMaxPoolSize(Integer.parseInt(ps.getProperty("maximumPoolSize", "100")));
            executorNew.setKeepAliveSeconds(Integer.parseInt(ps.getProperty("keepAliveTime", "120")));
            executorNew.setQueueCapacity(Integer.parseInt(ps.getProperty("initialCapacity", "1000000")));
            executorNew.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            executorNew.initialize();
            LOGGER.debug("【临时日志2】 初始化ThreadPoolTaskExecutor结束 executorNew的corePoolSize " + executorNew.getCorePoolSize());
        }catch (Exception e){
            throw new RuntimeException("初始化ThreadPoolTaskExecutor失败。");
        }
    }

     // --------- 新线程池end ---------

    private MyThreadPool(){
    }
    /**
     * 异步执行公共执行方法
     * @param command
     * @return future,返回异步等待对象
     */
    public static Future<Object> execute(IAsynchronousHandler command){

        ThreadPoolAdaptor handler = new ThreadPoolAdaptor(command,EXECUTETIME);
        Future<Object> future;
        // 是否使用新线程池
        Map<String,Object> userNewThreadPool =null; 
        // (Map<String,Object>)CFCenterUtils.getMap(CFCenterEnum.USE_NEW_THREADPOOL_BYIP);
        if(null != userNewThreadPool){
            // 是否全部机器适用
            Boolean allUser = (Boolean)userNewThreadPool.get("allUse");
            // 全部机器适用为否时，具体哪些机器适用新线程池机器IP列表
            List<String> ipStrList = null;
            Boolean localIPUseNewThreadPool= false;
            String localHostIp = "";
            Boolean needPrintLog = false;
            if(!allUser){
                // 减少调用获取本机IP的方法  都不适应的情况下才进行个别IP判断
                localHostIp = "" ; //LocalUtil.LOCAL_IP;
                ipStrList = (List<String>)userNewThreadPool.get("ipConfig");
                if(null != ipStrList && !ipStrList.isEmpty() && ipStrList.contains(localHostIp)){
                    localIPUseNewThreadPool = true;
                }
            }
            if(allUser || localIPUseNewThreadPool){
                // 判断新线程池参数配置是否需要进行修改
                executorNew = modityThredPool();
                needPrintLog = (Boolean)userNewThreadPool.get("needPrintLog");
                if(needPrintLog){
                    LOGGER.debug("【临时日志3】 配置中心allUser【" + allUser + "】 ipStrList【" + ipStrList + "】 本机IP【" + localHostIp + "】") ;
                }
                future = executorNew.submit(handler);
            }else{
                //future = execute.submit(handler);
                future = CommonThreadPool.execute(command);
            }
        }else{
            //future = execute.submit(handler);
            future = CommonThreadPool.execute(command);
        }
        return future;

    }
    /**
     * 关闭线程池
     * Description:
     * @return
     */
    @SuppressWarnings("unused")
//    private static boolean shutDown(){
//        if(execute != null){
//            execute.shutdown();
//            return true;
//        }
//        return false;
//    }

    private static Properties getThreadPoolConfig(){
        Properties ps = new Properties();
        InputStream in = MyThreadPool.class.getResourceAsStream("/orderThreadPoolConfig.properties");
        if(in == null){
            return null;
        }
        try {
            ps.load(in);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ps;
    }

    private static ExecutorService init(){
        Properties ps = getThreadPoolConfig();

        if(ps == null){
            throw new NullPointerException("找不到 threadpool 配置文件!");
        }

        int corePoolSize = Integer.parseInt(ps.getProperty("corePoolSize","5"));
        int maximumPoolSize = Integer.parseInt(ps.getProperty("maximumPoolSize","100"));
        int initialCapacity = Integer.parseInt(ps.getProperty("initialCapacity","20000"));
        long keepAliveTime = Long.parseLong(ps.getProperty("keepAliveTime","120"));
        String threadName = ps.getProperty("threadName", "lucky-order-threadPool-");
        ThreadPoolParameterVO vo = new ThreadPoolParameterVO();
        vo.setCorePoolSize(corePoolSize);
        vo.setMaximumPoolSize(maximumPoolSize);
        vo.setInitialCapacity(initialCapacity);
        vo.setKeepAliveTime(keepAliveTime);
        vo.setMaximumPoolSize(maximumPoolSize);
        vo.setThreadName(threadName);
        return CommonThreadPool.getThreadPool(vo);
    }

    private static ThreadPoolTaskExecutor modityThredPool(){

        Map<String,Integer> newThreadPoolConfig =null; 
        //(Map<String,Object>)CFCenterUtils.getMap(CFCenterEnum.NEW_THREADPOOL_CONFIG);

        if(null != newThreadPoolConfig){
            int corePoolSize = (int)newThreadPoolConfig.get("corePoolSize");
            int maxPoolSize = (int)newThreadPoolConfig.get("maximumPoolSize");
            int keepAliveSeconds = (int)newThreadPoolConfig.get("keepAliveTime");
            if(executorNew.getCorePoolSize() != corePoolSize
                    || executorNew.getMaxPoolSize() != maxPoolSize
                    || executorNew.getKeepAliveSeconds() != keepAliveSeconds){
                executorNew.setCorePoolSize(corePoolSize);
                executorNew.setMaxPoolSize(maxPoolSize);
                executorNew.setKeepAliveSeconds(keepAliveSeconds);
                //executorNew.setQueueCapacity((int)newThreadPoolConfig.get(RemoteThreadConstant.INITIALCAPACITY));//无法改变
                LOGGER.debug("【临时日志5 请在低峰期修改】 修改ThreadPoolTaskExecutor corePoolSize【" + executorNew.getCorePoolSize() + "】 maxPoolSize 【" + executorNew.getMaxPoolSize()
                        + "】keepAliveSeconds【" + executorNew.getKeepAliveSeconds() + "】") ;
            }
        }
        return executorNew;
    }
}
